home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Telnet Server 1.0 / MacSocket.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-01-14  |  7.0 KB  |  344 lines  |  [TEXT/KAHL]

  1. /*
  2.  Copyright © 1994 Mikhail Fridberg.
  3.  This is my implementation of BSD socket library for MacTCP.
  4.  It supports only limited number of socket calls
  5. */
  6.  
  7.  
  8. #include <MacTCPCommonTypes.h>
  9. #include <AddressXlation.h>
  10. #include <TCPPB.h>
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <errno.h>
  14. #include <time.h>
  15. #include <stddef.h>
  16. #include <string.h>
  17. #include "tcplow.h"
  18. #include "MacSocket.h"
  19.  
  20.  
  21.  
  22. void bzero(void *s, long size)
  23. {
  24. memset(s, 0L, size);
  25. }
  26.  
  27. /* Socket()  */
  28.  
  29.  
  30. long socket(long af, long type, long protocol)
  31. {
  32. OSErr    err;
  33. u_long    stream;
  34. u_long    recvLen;
  35. long        s = 0L;
  36. Ptr recvPtr = 0;
  37.  
  38. /* check for valid arguments, only TCP calls supported and only for 
  39.  Internet style addreses
  40. */
  41.  
  42. if (af != AF_INET) {
  43.         errno = EAFNOSUPPORT;
  44.         return -1;
  45.         }
  46. if (type != SOCK_STREAM) {
  47.         errno = ESOCKTNOSUPPORT;
  48.         return -1;
  49.         }
  50. if (protocol != 0L) {
  51.         errno = EPROTONOSUPPORT;
  52.         return -1;
  53.         }
  54.  
  55. /* Make buffer for the data */
  56.  
  57. recvLen = BUFF_SIZE;
  58. recvPtr = malloc(recvLen);
  59.  
  60. /* create a socket */
  61.  
  62. if ((err = MemError())==noErr) {
  63.                     err = LowTCPCreateStream(&stream,recvPtr,recvLen,(TCPNotifyProc)nil);
  64.                     } else 
  65.                 {
  66.                     errno = ENOBUFS;
  67.                     return -1;
  68.             }
  69.  
  70. /* check results */
  71.  
  72.     if (err == noErr) {
  73.                 errno = 0L;
  74.                 return stream;
  75.             } else
  76.     if (err == invalidLength) {
  77.                 errno = ENOBUFS;
  78.                 return -1;
  79.             } else
  80.     if (err == insufficientResources) {
  81.                 errno = EMFILE;
  82.                 return -1;
  83.             } else 
  84.         {
  85.     errno = err;
  86.     return -1;
  87.     }    
  88.  
  89. }
  90.  
  91.  
  92. /* Connect ()  */
  93.  
  94. long    connect (long s, struct sockaddr *name, long namelen)
  95. {
  96. OSErr            err;
  97. long            stream = 0L;
  98. tcp_port        kPort;
  99. ip_addr            ipAdress;
  100. byte            kTimeOut = 0x20;
  101. ip_addr            localHost = 0;
  102. tcp_port         localPort = 0;
  103.  
  104. stream = s;
  105. BlockMove(&name->sa_data[0],&kPort,sizeof(short));
  106. BlockMove(&name->sa_data[2],&ipAdress,sizeof(long));
  107.     
  108. err = LowTCPOpenConnection((StreamPtr)stream, kTimeOut, ipAdress,    kPort, &localHost, &localPort);
  109.  
  110.  
  111.     if (err == noErr) return 0L;
  112.  
  113.     if (err == streamAlreadyOpen) {
  114.             errno = EISCONN;
  115.             return -1;
  116.         } else
  117.     if (err == invalidStreamPtr) {
  118.             errno = EBADF;
  119.             return -1;
  120.         } else 
  121.     if (err == commandTimeout) {
  122.             errno = ETIMEDOUT;
  123.             return -1;
  124.         } else {
  125.              errno = err;
  126.              return -1;
  127.         }
  128. }
  129.  
  130. /* gethostbyname() */
  131.  
  132. struct hostent    *gethostbyname (char *name)
  133. {
  134. OSErr    err;
  135. u_long    addr,namelength;
  136. static    struct hostent    *myHost = 0L;
  137. static    struct hostInfo hInfo;
  138. Boolean done=false;
  139. long    len;
  140. static    char    *addrPtr = (char *)&hInfo.addr[0];
  141.  
  142. if (myHost == 0L)
  143.     myHost = (struct hostent *)malloc(sizeof(*myHost));
  144.  
  145. if (myHost == 0L) printf( "Could not create host entry, Error = %d\n",MemError());
  146.  
  147. if ((err = OpenResolver(nil)) != noErr) return NULL;
  148. err = StrToAddr(name, &hInfo, DNRResultProc, (char*)&done);
  149.     if (err == cacheFault) {
  150.         while (!done) GiveTime();
  151.         err = hInfo.rtnCode;
  152.     }
  153.     
  154.     if ((err == nameSyntaxErr) || (err == noNameServer) || (err == authNameErr) || 
  155.                         (err == noAnsErr) || (err == dnrErr) || (err == outOfMemory) || 
  156.                                                                 (err == notOpenErr)) {
  157.      free(myHost);
  158.      myHost = 0L;
  159.      CloseResolver();
  160.      return myHost;
  161.     }
  162.     
  163. CloseResolver();
  164. myHost->h_name = hInfo.cname;
  165. myHost->h_length = 4;
  166. myHost->h_addrtype = 2;
  167. myHost->h_addr_list = &addrPtr;
  168. return (myHost);
  169. }
  170.  
  171. /*recv ()*/
  172.  
  173. long recv (long s, char *buf, long len, long flags)
  174. {
  175.  
  176. Boolean        retry = false;
  177. OSErr        err;
  178. u_short        tempLen;
  179.  
  180. tempLen = len;
  181. if ((err = RecvData (s, buf, &tempLen, retry)) == noErr) return (long)tempLen;
  182. errno = err;
  183. return -1;
  184. }
  185.  
  186.  
  187. /* send() */
  188.  
  189. long send (long s, char *msg, long len, long flags)
  190. {
  191. OSErr        err;
  192.  
  193.  
  194. if ((err = SendData (s, msg, (u_short)len)) == noErr) return (long)len;
  195. errno = err;
  196. return -1;
  197. }
  198.  
  199.  
  200. /* shutdown() */
  201.  
  202. long shutdown (long s, long how)
  203. {
  204.         OSErr err;
  205.         switch (how) {
  206.             case 0L:
  207.             err = LowTCPClose(s, 0x20);
  208.             if (err != noErr && err != connectionDoesntExist &&
  209.                 err != connectionClosing && err != connectionTerminated) {
  210.                 LowTCPAbort(s);
  211.                 return err;
  212.             }        
  213.  
  214.             break;
  215.             case 1:
  216.                     err = LowTCPClose(s, 0x20);
  217.             if (err != noErr && err != connectionDoesntExist &&
  218.                 err != connectionClosing && err != connectionTerminated) {
  219.                     LowTCPAbort(s);
  220.                 return err;
  221.             }        
  222.             break;
  223.             case 2:
  224.             return LowTCPAbort(s);
  225.             break;
  226.  
  227.     }
  228.  
  229. }
  230.  
  231.  
  232. /* close() */
  233.  
  234. long socket_close (long s)
  235. {    
  236.     OSErr err;
  237.     Ptr recvPtr = 0L;
  238.     unsigned long recvLen;
  239.     
  240.     if ((err = LowTCPRelease(s,&recvPtr,&recvLen)) == noErr) free(recvPtr);
  241.     if (MemError() != noErr) printf("Could not free memory, Error = %d\n", MemError());
  242.     return err;
  243.  
  244. }
  245.  
  246. /* getserverbyname() */
  247. struct servent    *getservbyname(char *name, char *proto)
  248. {
  249. static    struct servent    *servInfo = 0L;
  250.  
  251. servInfo = (struct servent *)malloc(sizeof(*servInfo));
  252.  
  253. if (servInfo == 0L) printf("Could not allocate memory for server entry, Error= %d\n", MemError());
  254.  
  255. servInfo->s_port= 8000;
  256. servInfo->s_proto = name;
  257. return (servInfo);
  258. }
  259.  
  260. /* All following calls are not imlemented and commented out. I found that I never
  261. needed them, so I dfesided not to bother*/
  262.  
  263.  
  264. unsigned short htons(unsigned short hostshort)
  265. {
  266. /* It is probably not needed, so nothing here*/
  267. }
  268.  
  269.  
  270.  
  271.  
  272. /*
  273.  *    s_select(nfds, readfds, writefds, exceptfds, timeout)
  274.  *
  275.  *        select() examines the I/O descriptor  sets  whose  addresses
  276.  *        are  passed  in  readfds,  writefds, and exceptfds to see if
  277.  *        some of their descriptors are ready for reading,  ready  for
  278.  *        writing, or have an exceptional condition pending.  width is
  279.  *        the number of bits to be  checked  in  each  bit  mask  that
  280.  *        represent  a file descriptor; the descriptors from 0 through
  281.  *        width-1 in the  descriptor  sets  are  examined.   Typically
  282.  *        width  has  the  value  returned by getdtablesize for the
  283.  *        maximum number of file  descriptors.   On  return,  select
  284.  *        replaces  the  given descriptor sets with subsets consisting
  285.  *        of those descriptors that are ready for the requested opera-
  286.  *        tion.  The total number of ready descriptors in all the sets
  287.  *        is returned.
  288.  *
  289.  *        If timeout is not a NULL pointer,  it  specifies  a  maximum
  290.  *        interval  to wait for the selection to complete.  If timeout
  291.  *        is a NULL  pointer,  the  select  blocks  indefinitely.   To
  292.  *        effect  a  poll,  the  timeout argument should be a non-NULL
  293.  *        pointer, pointing to a zero-valued timeval structure.
  294.  *
  295.  *        Any of readfds, writefds, and exceptfds may be given as NULL
  296.  *        pointers if no descriptors are of interest.
  297.  *
  298.  *        Using select to open a socket for reading is analogous  to
  299.  *        performing an accept call.
  300.  *
  301.  *        select() returns the number of ready  descriptors  that  are
  302.  *        contained  in  the  descriptor  sets,  or  -1  if  an  error
  303.  *        occurred.  If the time limit expires then  select()  returns
  304.  *        0.   If select() returns with an error the descriptor sets 
  305.  *      will be unmodified.
  306.  */
  307. /*
  308. int s_select( long nfds, long *readfds, long *writefds, 
  309.                 long *exceptfds, struct timeval *timeout)
  310. {
  311. long count = 0;
  312.  
  313.     while (count < nfds || !timeout) {
  314.         check_reads(readfds, count);
  315.         check_writes(writefds, count);
  316.         check_except(exceptfds, count);
  317.         count++;
  318.         
  319.             
  320.         }
  321.  
  322.  
  323. }
  324.  
  325. check_reads (long *readfds, long count)
  326. {
  327.  
  328.  
  329. }
  330.  
  331.  
  332. check_writes (long *readfds, long count)
  333. {
  334.  
  335.  
  336. }
  337.  
  338. check_except (long *readfds, long count)
  339. {
  340.  
  341.  
  342. }
  343.  
  344. */